package com.elai.tags.controller;

import java.util.*;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.elai.common.annotation.Log;
import com.elai.common.constant.HttpStatus;
import com.elai.common.constant.ThirdInterface;
import com.elai.common.core.domain.AjaxResult;
import com.elai.common.core.text.Convert;
import com.elai.common.enums.BusinessType;
import com.elai.common.utils.DateUtils;
import com.elai.common.utils.ThirdProperties;
import com.elai.common.utils.WebUtils;
import com.elai.common.utils.poi.ExcelUtil;
import com.elai.common.utils.sql.SqlTableUtil;
import com.elai.tags.domain.*;
import com.elai.tags.service.*;
import com.elai.common.core.controller.BaseController;
import com.elai.common.core.page.TableDataInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 用户标签Controller
 *
 * @author elai
 * @date 2021-06-27
 */
@RestController
@RequestMapping("/tag/info")
public class BaseUserTagsController extends BaseController
{
    private static final Logger log = LoggerFactory.getLogger(BaseUserTagsController.class);
    @Autowired
    private BaseUserTagsService baseUserTagsService;

    @Autowired
    private BaseUserTagsLevelService baseUserTagsLevelService;

    @Autowired
    private ThirdProperties thirdProperties;

    @Autowired
    private IBaseUserTagsTaskDetailService baseUserTagsTaskDetailService;
    @Autowired
    private IBaseUserTagsLevelTaskDetailService baseUserTagsLevelTaskDetailService;

    @Autowired
    private BaseTagsTypeService baseTagsTypeService;

    /**
     * 查询用户标签列表
     */
    @PreAuthorize("@ss.hasPermi('tag:info:list')")
    @GetMapping("/list")
    public TableDataInfo list(BaseUserTagsDO baseUserTags)
    {
        startPage();
        List<BaseUserTagsDO> list = baseUserTagsService.selectBaseUserTagsList(baseUserTags);
        return getDataTable(list);
    }

    /**
     * 获取用户标签详细信息
     */
    @PreAuthorize("@ss.hasPermi('tag:info:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return AjaxResult.success(baseUserTagsService.selectBaseUserTagsById(id));
    }

    /**
     * 导出用户标签列表
     */
    @PreAuthorize("@ss.hasPermi('tag:info:export')")
    @Log(title = "用户标签", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(BaseUserTagsDO baseUserTags)
    {
        List<BaseUserTagsDO> list = baseUserTagsService.selectBaseUserTagsList(baseUserTags);
        ExcelUtil<BaseUserTagsDO> util = new ExcelUtil<BaseUserTagsDO>(BaseUserTagsDO.class);
        return util.exportExcel(list, "info");
    }


    @GetMapping(value = "/getUsertagsByType/{id}")
    public AjaxResult getUsertagsByType(@PathVariable("id") Integer id)
    {
        BaseUserTagsDO baseUserTags=new BaseUserTagsDO();
        baseUserTags.setTagType(id);
        List<BaseUserTagsDO> list = baseUserTagsService.selectBaseUserTagsList(baseUserTags);
        return AjaxResult.success(list);
    }

    /**
     * 获取用户标签详细信息
     */
    @GetMapping(value = "/userTagsDetail/{id}")
    public AjaxResult userTagsDetail(@PathVariable("id") Long id)
    {
        BaseUserTagsDO userTags =baseUserTagsService.selectBaseUserTagsById(id);
        BaseUserTagsLevelDO levels=new BaseUserTagsLevelDO();
        levels.setTagsId(userTags.getId());
        List<BaseUserTagsLevelDO>  list=baseUserTagsLevelService.selectBaseUserTagsLevelList(levels);
        userTags.setTagsLevelList(list);

        Map<String,Object> resultMap=new HashMap();
        List title=new ArrayList();
        List<Long> chartData=new ArrayList<>();
        StringBuffer remark=new StringBuffer();
        list.stream().forEach(taskDetail->{
            title.add(taskDetail.getLevelName());
            chartData.add(taskDetail.getResultNum());
            if(remark.length()>0){
                remark.append(",");
            }
            remark.append(taskDetail.getLevelName());
        });
        userTags.setTagsDescription(remark.toString());
        Map<String,Object> dataMap1=new HashMap();
        dataMap1.put("name","标签统计结果");
        dataMap1.put("type","bar");
        dataMap1.put("data",chartData);

        resultMap.put("tableData",list);
        resultMap.put("chartData",dataMap1);
        resultMap.put("chartTitle",title);
        resultMap.put("tagsInfo",userTags);

        return AjaxResult.success(resultMap);
    }

    @GetMapping(value = "/getUserTagsInfo/{id}")
    public AjaxResult getUserTagsInfo(@PathVariable("id") Long id)
    {
        BaseUserTagsDO userTags =baseUserTagsService.selectBaseUserTagsById(id);
        BaseUserTagsLevelDO levels=new BaseUserTagsLevelDO();
        levels.setTagsId(userTags.getId());
        List<BaseUserTagsLevelDO>  list=baseUserTagsLevelService.selectBaseUserTagsLevelList(levels);
        userTags.setTagsLevelList(list);
        return AjaxResult.success(userTags);
    }


    /**
     * 修改用户标签
     */
    @PreAuthorize("@ss.hasPermi('tag:info:edit')")
    @Log(title = "用户标签", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody BaseUserTagsDO baseUserTags)
    {
        return toAjax(baseUserTagsService.updateBaseUserTags(baseUserTags,null));
    }

    /**
     * 删除用户标签
     */
    @PreAuthorize("@ss.hasPermi('tag:info:remove')")
    @Log(title = "用户标签", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(baseUserTagsService.deleteBaseUserTagsByIds(ids));
    }


    @PreAuthorize("@ss.hasPermi('tag:info:add')")
    @Log(title = "添加用户标签", businessType = BusinessType.INSERT)
    @PostMapping("/createUserTags")
    public AjaxResult createUserTags(@RequestBody String requestJson)throws Exception{
        logger.info(requestJson);
        JSONObject jsonObj=JSONObject.parseObject(requestJson);
        JSONObject object=jsonObj.getJSONObject("requestJson");
        BaseUserTagsDO userTagsdo=JSONObject.parseObject(object.toJSONString(),BaseUserTagsDO.class);
        String tableName= SqlTableUtil.getTagName();
        userTagsdo.setName(tableName);
        userTagsdo.setTagsRule(object.toJSONString());
        object.put("tableId",userTagsdo.getName());
        object.put("tableType","ADD");
        //ck掉不通，测试的通把注释以及下面两个代码去掉
        JSONObject obj=WebUtils.postCkObj(thirdProperties.getCkUrl(), ThirdInterface.create_tags_users,object);

        if (obj == null || obj.getInteger("code") != HttpStatus.CK_SUCCESS){
            AjaxResult.error(obj.getString("msg"));
        }
        JSONObject data= obj.getJSONObject("data");
        JSONArray array=data.getJSONArray("levelData");
        userTagsdo.setResultTime(DateUtils.getNowDate());
        Long countTotal=data.getLong("total");
        userTagsdo.setResultNum(countTotal);
        userTagsdo.setUpdateTime(DateUtils.getNowDate());
        baseUserTagsService.insertBaseUserTags(userTagsdo,object,array);
        addTaskDetail(userTagsdo,countTotal);
        String executorParam="url: "+thirdProperties.getLocalUrl()+ThirdInterface.tagsXxJobTask+"/"+userTagsdo.getName()+"\n" +
                "method: get";
        JSONObject requestInfo = new JSONObject();
        requestInfo.put("jobGroup",1);
        requestInfo.put("scheduleType","CRON");
        requestInfo.put("jobDesc",userTagsdo.getDisplayName());
        requestInfo.put("executorRouteStrategy","FIRST");
        requestInfo.put("scheduleConf","31 0 0 * * ?");
        requestInfo.put("misfireStrategy","FIRE_ONCE_NOW");
        requestInfo.put("glueType","BEAN");
        requestInfo.put("executorHandler","httpUserTagsJobHandler");
        requestInfo.put("executorBlockStrategy","SERIAL_EXECUTION");
        requestInfo.put("executorTimeout",5);
        requestInfo.put("executorFailRetryCount",1);
        requestInfo.put("author","admin");
        requestInfo.put("alarmEmail","229049640@qq.com");
        requestInfo.put("executorParam",executorParam);
        requestInfo.put("glueRemark",userTagsdo.getDisplayName()+"定时任务");
        JSONObject response= WebUtils.postCkObj(thirdProperties.getXxjobUrl(),ThirdInterface.createJobInfo,requestInfo);
        if(response.containsKey("code")&&200==response.getIntValue("code")){
            return AjaxResult.success();
        }else{
            return AjaxResult.error("调用api接口失败！");
        }
    }

    @Log(title = "预估用户分群数量", businessType = BusinessType.OTHER)
    @PostMapping("/calcUserTagsNumber")
    public AjaxResult calcUserTagsNumber(@RequestBody String requestJson){
        logger.info(requestJson);
        logger.info(thirdProperties.getCkUrl());
        JSONObject jsonObj=JSONObject.parseObject(requestJson);
        Map<String, Object> object=jsonObj.getJSONObject("requestJson");
        JSONObject obj= WebUtils.postCkObj(thirdProperties.getCkUrl(), ThirdInterface.find_tags_count,object);
        if (obj == null || obj.getInteger("code") != HttpStatus.CK_SUCCESS){
            AjaxResult.error(obj.getString("msg"));
        }
        return AjaxResult.success(Convert.toInt(obj.getString("data")));
    }

    @GetMapping(value = "/getUserinfotagsByType/{id}")
    public AjaxResult getUserinfotagsByType(@PathVariable("id") Long id)
    {

//        List<String> tableList = new ArrayList<>();
        BaseTagsTypeDO type=new BaseTagsTypeDO();
        type.setParentId(0L);
        List<BaseTagsTypeDO> parentList = baseTagsTypeService.selectBaseTagsTypeList(type);

        BaseUserTagsDO baseUserTags=new BaseUserTagsDO();
        List<BaseUserTagsDO> list = baseUserTagsService.selectBaseUserTagsList(baseUserTags);

        Map<Integer,List<BaseUserTagsDO>> groupTags = list.stream().collect(
                Collectors.groupingBy(a -> a.getTagType()));

        List<String> tableList = list.stream().map(e -> e.getName()).distinct().collect(Collectors.toList());
        Map<String,Object> param = new HashMap<>();
        param.put("tableList",tableList);
        param.put("distinctId",id);

        JSONObject obj= WebUtils.postCkObj(thirdProperties.getCkUrl(), ThirdInterface.find_user_tags,param);
        if (obj == null || obj.getInteger("code") != HttpStatus.CK_SUCCESS){
            AjaxResult.error(obj.getString("msg"));
        }
        List<String> resTagsList = obj.getJSONArray("data").toJavaList(String.class);

        List<Map> mapList = new ArrayList<>();
        Map<String,Object> resMap = new HashMap<>();
        int allTagCount = 0;
        for (BaseTagsTypeDO tagsTypeDO : parentList){
            Map map=new HashMap();
            map.put("id",tagsTypeDO.getId());
            map.put("type","type");
            map.put("label",tagsTypeDO.getTypeName());
            List<Map> childList = new ArrayList<>();
//            if (groupTags.containsKey(tagsTypeDO.getId())){
            List<BaseUserTagsDO> tagsDOList = groupTags.get(tagsTypeDO.getId().intValue());
            if (tagsDOList != null){
                allTagCount = allTagCount + tagsDOList.size();
                for (BaseUserTagsDO userTagsDO : tagsDOList){
                    Map<String,Object> child=new HashMap<>();
                    child.put("id",userTagsDO.getId());
                    child.put("type","type");
                    String labelName = userTagsDO.getDisplayName()+":"+"未知";
                    child.put("label",labelName);
                    String checkName = getCheckTag(resTagsList,userTagsDO.getName());
                    if (checkName != null){
                        labelName = userTagsDO.getDisplayName()+":"+checkName;
                        child.put("label",labelName);
                    }
                    childList.add(child);
                }
            }

//            }
            map.put("children",childList);

            mapList.add(map);

        }
        log.info("getUserinfotagsByType=:"+JSONObject.toJSONString(mapList));
        resMap.put("mapList",mapList);
        resMap.put("allTagCount",allTagCount);

        return AjaxResult.success(resMap);
    }

    @GetMapping(value = "/userTagsXxjobTask/{name}")
    public AjaxResult userTagsXxjobTask(@PathVariable("name") String name)
    {
        log.info("分群["+name+"]调度任务开始执行");
        BaseUserTagsDO tags=new BaseUserTagsDO();
        tags.setName(name);
        List<BaseUserTagsDO> tagsList=baseUserTagsService.selectBaseUserTagsList(tags);
        if(tagsList.size()==1){
            tags=tagsList.get(0);
            JSONObject object=(JSONObject)JSONObject.toJSON(tags);
            object.put("tableId",tags.getName());
            object.put("tableType","Task");
            object.put("groupRule",tags.getTagsRule());
            JSONObject obj= WebUtils.postCkObj(thirdProperties.getCkUrl(), ThirdInterface.create_tags_users,object);
            if (obj == null || obj.getInteger("code") != HttpStatus.CK_SUCCESS){
                logger.info("执行定时任务失败，"+obj);
                return AjaxResult.error("执行失败,原因："+obj.getString("msg"));
            }
            JSONObject data= obj.getJSONObject("data");
            JSONArray array=data.getJSONArray("levelData");
            tags.setResultTime(DateUtils.getNowDate());
            Long countTotal=data.getLong("total");
            tags.setResultNum(countTotal);
            tags.setStatus("02");
            tags.setResultTime(DateUtils.getNowDate());
            tags.setUpdateTime(DateUtils.getNowDate());
            baseUserTagsService.updateBaseUserTags(tags,array);
            addTaskDetail(tags, countTotal);
        }
        else{
            AjaxResult.error("分群ID["+name+"]查询数据错误");
        }
        return AjaxResult.success("执行成功");
    }

    private void addTaskDetail(BaseUserTagsDO tags, Long num) {
        //新添加一条执行记录
        BaseUserTagsTaskDetail detail=new BaseUserTagsTaskDetail();
        detail.setBatchNo(DateUtils.dateTime());
        detail.setTagsId(Long.valueOf(tags.getId()+""));
        detail.setTagsCode(tags.getName());
        detail.setTagsName(tags.getDisplayName());
        detail.setTaskTime(DateUtils.getNowDate());
        detail.setResultNum(num !=null? num.intValue():0);
        detail.setResultTime(DateUtils.getNowDate());
        detail.setTaskStatus("02");
        baseUserTagsTaskDetailService.insertBaseUserTagsTaskDetail(detail);
        List<BaseUserTagsLevelDO> levelList=tags.getTagsLevelList();
        levelList.stream().forEach(level->{
            BaseUserTagsLevelTaskDetail d=new BaseUserTagsLevelTaskDetail();
            d.setTagsId(level.getTagsId());
            d.setTagsCode(tags.getName());
            d.setTagsName(tags.getDisplayName());
            d.setLevelName(level.getLevelName());
            d.setTaskTime(DateUtils.getNowDate());
            d.setTagsLevel(level.getTagsLevel());
            d.setBatchNo(DateUtils.dateTime());
            d.setResultNum(level.getResultNum().intValue());
            d.setResultTime(DateUtils.getNowDate());
            d.setTaskStatus("02");
            baseUserTagsLevelTaskDetailService.insertBaseUserTagsLevelTaskDetail(d);
        });
    }

    private String getCheckTag(List<String> tags,String tagName){

        Optional<String> result = tags.stream().filter(x -> x.contains(tagName)).findFirst();
        if (result.isPresent()) {
            // 存在
            String checkTag =  result.get();
            return checkTag.indexOf("#")>-1?checkTag.split("#")[1]:checkTag;
        } else {
            // 不存在
        }
        return null;
    }
}
